#!/usr/bin/env python
# -*- coding: utf-8; -*-
"""
用户账户相关功能：注册、短信、登录、注销
"""
from io import BytesIO
import uuid
import datetime

from django.shortcuts import render, redirect, reverse
from django.http import HttpResponse, JsonResponse
from django.db.models import Q

from web import models
from web.forms.account import (LoginForm, LoginEmailForm, RegisterForm,
                               AuthEmailForm, AuthSmsForm)
from utils.image_code import check_code


def login(request):
    """用户名、邮箱密码登录"""
    if request.method == 'GET':
        form = LoginForm(request)
        return render(request, 'web/login.html', {'form': form})

    # 图片验证码获取后，保存到服务器 session 中，为了验证是否正确，可以把
    # request 对象作为参数传递给表单类，或者 request.session
    form = LoginForm(request.session, request.POST)
    if form.is_valid():
        account = form.cleaned_data['account']
        password = form.cleaned_data['password']
        # user_obj = models.UserInfo.objects.filter(name=account,
        #                                           password=password).first()
        user_obj = models.UserInfo.objects.filter(
            Q(name=account)
            | Q(email=account)).filter(password=password).first()
        if user_obj:
            ############################################################
            # 登录成功，session 保存用户ID(数据库存储)和过期时间(session存储) #
            ############################################################
            request.session['user_id'] = user_obj.id
            request.session.set_expiry(60 * 60 * 24 * 14)
            # return redirect(reverse('index'))
            return redirect('index')
        form.add_error('account', '用户名或密码错误')
    return render(request, 'web/login.html', {'form': form})


def login_sms(request):
    """手机验证码登录"""
    return HttpResponse('logining')


def login_email(request):
    """邮箱验证码登录"""
    if request.method == 'GET':
        form = LoginEmailForm()
        # return render(request, 'web/login_email.html', {'form':form})
        return render(request, 'web/login_email.html', {'form': form})

    form = LoginEmailForm(request.POST)
    if form.is_valid():
        user_obj = form.cleaned_data['email']  # email 实际对应一个用户对象

        # 用户信息放入 session 中
        request.session['user_id'] = user_obj.id
        # request.session['user_name'] = user_obj.name
        request.session.set_expiry(60 * 60 * 24 * 14)

        return JsonResponse({"status": True, 'url': reverse('index')})
    return JsonResponse({"status": False, 'errors': form.errors})


def register(request):
    """注册"""
    if request.method == 'GET':
        form = RegisterForm()
        return render(request, 'web/register.html', {'form': form})

    if request.method == 'POST':
        form = RegisterForm(request.POST)
        if form.is_valid():
            # 验证通过(验证过程密码已经被加密)，将 model 有关数据写入数据库
            # form.save()

            # 用户表中新建一条数据（注册）
            instance = form.save()

            # 创建交易记录

            # 新注册用户默认个人免费版
            policy_obj = models.Package.objects.filter(
                category=1, title="个人免费版").first()

            models.Transaction.objects.create(
                status=2,
                order=str(uuid.uuid4()),
                user=instance,
                # package 作为外键，不可为空，而刚注册用户对应的 policy_obj 为空
                # 所以有必要执行项目目录 script 中的 init_pricepolicy.py 文件，优先生成一条
                # 价格策略记录，否则关于 package 会报错约束“不能为空”被
                # django.db.utils.IntegrityError:
                #   NOT NULL constraint failed: web_transaction.package_id
                package=policy_obj,
                count=0,
                price=0,
                start_datetime=datetime.datetime.now())

            # 注册成功后，重定向到手机或邮箱密码登录页面(将新页面 url 返回给 ajax 请求)
            return JsonResponse(data={"status": True, 'newurl': '/login/'})

        return JsonResponse(data={'status': False, 'errors': form.errors})


def auth_code_email(request):
    """邮件发送验证码：登录、注册"""

    form = AuthEmailForm(request.POST)
    # 表单校验, 邮箱是否已被注册、邮件模板是否正确(爬虫程序设置模板参数可能错误)
    if form.is_valid():
        return JsonResponse({'status': True})
    else:
        return JsonResponse({'status': False, 'errors': form.errors})


def auth_code_image(request):
    """生成图片验证码"""
    image_object, code = check_code()

    request.session['auth_code_image'] = code
    request.session.set_expiry(60)  # 主动修改session的过期时间为60s

    stream = BytesIO()
    image_object.save(stream, 'png')
    return HttpResponse(stream.getvalue())


def auth_code_sms(request):
    """短信发送验证码"""
    form = AuthSmsForm(request.POST)
    if form.is_valid():
        JsonResponse({'status': True})
    else:
        return JsonResponse({'status': False, 'errors': form.errors})


def logout(request):
    request.session.flush()
    return redirect('index')
